<!DOCTYPE html>
{% autoescape true %}
<html>
    <head>
        <title>Using JSON in Templates</title>
        <link href='/css/base.css' rel='stylesheet' type='text/css'></link>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
        <script src="/js/json.js"></script>

        <!-- some json data from the template values-->
        <script id="init_data" type="application/json">
            {{ json }}
        </script>          

        <!-- by using the safe filter, you allow un-encoded input to be rendered directly, this will result XSS -->
        <!--script id="xss_data" type="application/json">
            {{ json | safe }}
        </script--> 

        <style>
            .user_input{
                border:1px solid black;
                padding: 10px;
                margin: 10px;
            }
        </style>
    </head>

    <body>        
        <h1>XSS Defence: Using JSON</h1>

        <h1>Case 1: Template</h1>

        <div>In this demo, we want to render some html from the json data from the templates. 
            If we use inline script to directly evaluate the json data, the page is vulnerable to XSS attacks if the json data is untrusted. 
            Inline script is also not allowed if the application is using <a href="http://www.html5rocks.com/en/tutorials/security/content-security-policy/">Content Security Policy</a>
        </div>  
        <br>
        <div>The use case below might not be common when document loading, because you might just process the data using the template logic. (e.g. { { some_data } })</div>

        <div class="user_input">
            <div>The following is the untrusted input:</div>            
            <div>{</div>
            <div id="content"></div>
            <div>}</div>
        </div>
        <br>

        <div>Study the source on server and client carefully to see what would result an XSS attack</div>

        <h2>A Secure Approach</h2>
        <ul>
            <li>Encode the json input in script tag with type="application/json"</li>
            <li>Decode the json in external javascript</li>
            <li>Parse the json</li>
            <li>Render the data as text</li>
            <li>It is important that throughout the rendering process, the untrusted input should NEVER be rendered as HTML.</li>
        </ul>     
        <hr>

        <h1>Case 2: Ajax</h1>
        <div>The following use case is very common. The page needs to request json data from the server and render the data to the HTML dynamically</div>

        Click this button to load some json data from server<input type="button" id="ajaxButton" value="Load JSON"/>
        <div class="user_input">
            <div>The following is the untrusted input:</div>
            <div>{</div>
            <div id="dynamic_content" class="user_input"></div>
            <div>}</div>
        </div>
        <div>Feel free to challenge the above approach!</div>
        
        <a href="/">Home</a>
    </body>
</html>

{% endautoescape %}